package net.huazai.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import net.huazai.entity.LoginUser;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 11987
 */
@Slf4j
public class JwtUtil{
    /**
     *  AccessToken 过期时间，正常过期时间 7 天
     */
    private static final long EXPIRE = 1000L * 60 * 60 * 24 * 7;

    /**
     *  RefreshToken 过期时间，正常过期时间 30 天
     */
    public static final long REFRESH_EXPIRE = 1000L * 60 * 60 * 24 * 30;


    /**
     * 加密的密钥
     */
    private static final String SECRET = "huazai-ecshop-1234";

    /**
     * token 前缀
     */
    private static final String TOKEN_PREFIX = "ecshop";

    /**
     * SUBJECT
     */
    private static final String SUBJECT = "huazai";

    /**
     * 根据用户信息，生成 JWT 令牌
     * @return  Map
     */
    public static Map<String,Object> generatorJwt(LoginUser loginUser) {
        if (loginUser == null) {
            throw new NullPointerException("登录对象为空");
        }

        // 过期时间
        Date expireTime = new Date(System.currentTimeMillis() + EXPIRE);

        // 生成 JWT
        String token = Jwts.builder().setSubject(SUBJECT)
                // payload
                .claim("id", loginUser.getId())
                .claim("name", loginUser.getName())
                .claim("head_avatar", loginUser.getHeadAvatar())
                .claim("mail", loginUser.getMail())
                .setIssuedAt(new Date())
                // 当前时间 + 过期时间
                .setExpiration(expireTime)
                // 加密算法
                .signWith(SignatureAlgorithm.HS256, SECRET)
                .compact();

        // 加前缀区分业务
        token = TOKEN_PREFIX + token;
        Map<String,Object> result = new HashMap<>();
        result.put("AccessToken", token);
        result.put("AccessTokenExpireTime", expireTime);
        result.put("RefreshToken", CommonUtil.generateUuid());
        log.info("公共服务-生成 token：{}，过期时间：{}, 结果：{}", token, expireTime, result);
        return result;
    }

    /**
     * 校验 token 是否正确
     * @param token token
     * @return  Claims
     */
    public static Claims checkJwt(String token) {
        try {
            final Claims claims = Jwts.parser()
                    .setSigningKey(SECRET)
                    .parseClaimsJws(token.replace(TOKEN_PREFIX, ""))
                    .getBody();
            log.info("公共服务-解密 token 成功：{}", claims);
            return claims;
        } catch (Exception e) {
            log.error("公共服务-解密 token 失败：{}", e);
            return null;
        }
    }
}
